function fmr = hdr_Dyn3DToFMR(hfile, fmrname, nvols, vlayout)
% HDR::Dyn3DToFMR  - convert a dynamics 3D Analyze into FMR/STC
%
% FORMAT:       [fmr] = hdr.Dyn3DToFMR(fmrname, nvols, vlayout)
%
% Input fields:
%
%       fmrname     target FMR filename, STC prefix will be generated
%       nvols       number of volumes in file
%       vlayout     either 'TxS' or 'SxT' to indicate that either
%                   the temporal domain is looped through first (TxS) or
%                   the slice domain is looped through first (SxT)
%
% Output fields:
%
%       fmr         created FMR object (with slices loaded)

% Version:  v0.7g
% Build:    9100721
% Date:     Oct-07 2009, 9:34 PM CEST
% Author:   Jochen Weber, SCAN Unit, Columbia University, NYC, NY, USA
% URL/Info: http://wiki.brainvoyager.com/BVQXtools

% argument check
if nargin ~= 4 || ...
    numel(hfile) ~= 1 || ...
   ~isBVQXfile(hfile, 'hdr') || ...
   ~ischar(fmrname) || ...
    isempty(fmrname) || ...
   ~isa(nvols, 'double') || ...
    numel(nvols) ~= 1 || ...
    isinf(nvols) || ...
    isnan(nvols) || ...
    nvols < 1 || ...
    nvols ~= fix(nvols) || ...
   ~ischar(vlayout) || ...
   ~any(strcmpi(vlayout(:)', {'sxt', 'txs'}))
    error( ...
        'BVQXfile:BadArgument', ...
        'Invalid call to %s.', ...
        mfilename ...
    );
end
fmrname = fmrname(:)';
vlayout = vlayout(:)';

% get settings from HDR and make sure the voxel data is loaded
try
    hdr_LoadVoxelData(hfile);
    hdrs = bvqxfile_getscont(hfile.L);
    hdrc = hdrs.C;
    iImg = hdrc.ImgDim;
    iDim = iImg.Dim;
    iRes = iImg.PixSpacing;
    dimX = iDim(3);
    dimY = iDim(2);
    dimZ = iDim(4) / nvols;
    if dimZ ~= fix(dimZ)
        error('Bad nvols argument');
    end
    resX = iRes(3);
    resY = iRes(2);
    resZ = iRes(4);
catch
    error( ...
        'BVQXfile:InternalError', ...
        'Error inspecting HDR object: ''%s''.', ...
        lasterr ...
    );
end

% determine range
minvox = double(min(hdrc.VoxelData(:)));
maxvox = double(max(hdcr.VoxelData(:)));
rangef = (maxvox - minvox) / 4095;

% make some initial FMR project settings
fmr = BVQXfile('new:fmr');
fmrc = bvqxfile_getcont(fmr.L);
fmrc.FileVersion = 5;
fmrc.DataStorageFormat = 2;
fmrc.NrOfVolumes = nvols;
fmrc.NrOfSlices = dimZ;
fmrc.Prefix = stcpref;
fmrc.TR = 3000;
fmrc.InterSliceTime = fix(fmrc.TR / dimZ);
fmrc.ResolutionX = dimX;
fmrc.ResolutionY = dimY;
fmrc.LayoutNColums = ceil(sqrt(dimZ)) + 1;
fmrc.LayoutNRows = ceil(dimZ / fmrc.LayoutNColums);
fmrc.InplaneResolutionX = resX;
fmrc.InplaneResolutionY = resY;
fmrc.SliceThickness = resZ;
fmrc.SliceGap = 0;
fmrc.Slice1CenterZ = -resZ * (dimZ - 1) / 2;
fmrc.SliceNCenterZ =  resZ * (dimZ - 1) / 2;
fmrc.NRows = dimX;
fmrc.NCols = dimY;
fmrc.FoVRows = dimX * resX;
fmrc.FoVCols = dimY * resY;
fmrc.GapThickness = 0;
fmrc.FirstDataSourceFile = hdrs.F;
fmrc.Slice = [];
bvqxfile_setcont(fmr.L, fmrc);
try
    fmr = aft_SaveAs(fmr, fmrname);
    fmrc = bvqxfile_getcont(fmr.L);
catch
    BVQXfile(0, 'clearobj', fmr.L);
    error( ...
        'BVQXfile:FileSaveError', ...
        'Error saving FMR file to disk: ''%s''.', ...
        lasterr ...
    );
end

% generate slice objects and put into fmr structure
stcd = uint16([]);
stcd(dimY, dimX, nvols, dimZ) = uint16(0);
for sc = 1:dimZ
    if strcmpi(vlayout, 'sxt')
        stcd(:, :, :, sc) = uint16(rangef * ...
            (single(hdrc.VoxelData(:, :, sc:nvols:end)) - minvox));
    else
        stcd(:, :, :, sc) = uint16(rangef * ...
            (single(hdrc.VoxelData(:, :, (sc - 1) * nvols + 1:sc * nvols)) - minvox));
    end
end

% put Slice into FMR and save to get transio
fmrc.Slice = struct;
fmrc.Slice.STCData = stcd;
bvqxfile_setcont(fmr.L, fmrc);
try
    fmr_SaveSTC(fmr, true);
catch
    BVQXfile(0, 'clearobj', fmr.L);
    error( ...
        'BVQXfile:FileSaveError', ...
        'Error saving FMR file to disk: ''%s''.', ...
        lasterr ...
    );
end
